﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;

using System.Reflection;

namespace SPWorkflows
{
    public partial class frmRestartWorkflows : Form
    {
        public string siteName, listName, workflowName;
        public SPWorkflowAssociationCollection objWorkflowAssociationCollection = null;
        public SPWorkflowManager objWorkflowManager = null;
        public SPListItem listItemforRestarting = null;

        public frmRestartWorkflows()
        {
            InitializeComponent();
        }

        private void frmRestartWorkflows_Load(object sender, EventArgs e)
        {
            try
            {
                txtWebName.Text = siteName;
                txtListName.Text = listName;
                txtWorkflowName.Text = workflowName;
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// Populate the workflows in error based on SPWorkflowStatus Enumeration
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPopulate2_Click(object sender, EventArgs e)
        {
            try
            {
                checkedListBox1.Items.Clear();
                using (SPSite site = new SPSite(siteName))
                {
                    SPWeb web = site.OpenWeb();
                    SPList list = web.Lists[listName];

                    objWorkflowAssociationCollection = list.WorkflowAssociations;

                    foreach (SPListItem listItem in list.Items)
                    {
                        foreach (SPWorkflow wf in listItem.Workflows)
                        {
                            if (wf.ParentAssociation.Name == workflowName)
                            {
                                Guid wfInstanceID = wf.InstanceId;
                                var workflowStatusValue = listItem[workflowName];

                                SPWorkflowAssociation wfAssociation = list.WorkflowAssociations[wf.AssociationId];
                                string workflowStatusString = System.Enum.GetName(typeof(SPWorkflowStatus), Convert.ToInt32(workflowStatusValue));

                                //**************************************************************************************
                                // Here you can change the Workflow Status for further action 
                                //**************************************************************************************

                                if (workflowStatusString == SPWorkflowStatus.ErrorOccurred.ToString()) // (workflowStatusString == SPWorkflowStatus.ErrorOccurred.ToString()) 
                                {
                                    checkedListBox1.Items.Add(listItem.Name);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " Error in Load of Errored Workflows");
            }
        }

        /// <summary>
        /// Restart the workflows in error
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRestart_Click(object sender, EventArgs e)
        {
            try
            {
                #region To Restart the Workflow
                string[] checkedItems = GetCheckedItems();

                if (checkedItems != null)
                {
                    try
                    {
                        using (SPSite site = new SPSite(siteName))
                        {
                            SPWeb web = site.OpenWeb();
                            SPList list = web.Lists[listName];
                            SPWorkflowCollection workflowCollection;
                            string result = string.Empty;

                            int count = checkedItems.Length - 1;
                            int n = 0;

                            objWorkflowAssociationCollection = list.WorkflowAssociations;

                            foreach (SPListItem listItem in list.Items)
                            {
                                workflowCollection = listItem.Workflows;

                                for (int x = 0; x < workflowCollection.Count; x++)
                                {
                                    SPWorkflow wf = workflowCollection[x];
                                    if (wf.ParentAssociation.Name == workflowName)
                                    {
                                        Guid wfInstanceID = wf.InstanceId;
                                        var workflowStatusValue = listItem[workflowName];

                                        SPWorkflowAssociation wfAssociation = list.WorkflowAssociations[wf.AssociationId];
                                        string workflowStatusString = System.Enum.GetName(typeof(SPWorkflowStatus), Convert.ToInt32(workflowStatusValue));

                                        if (n <= count)
                                        {
                                            string checkedItemName = checkedItems[n].ToString();

                                            if (listItem.Name == checkedItemName)
                                            {
                                                SPWorkflowManager.CancelWorkflow(wf);
                                                objWorkflowManager = list.ParentWeb.Site.WorkflowManager;
                                                objWorkflowManager.StartWorkflow(listItem, wfAssociation, "", true);
                                                n++;
                                                result += checkedItemName + "\n";
                                            }
                                        }
                                    }
                                }
                            }
                            MessageBox.Show(result + " is/are Restarted.", "Information");
                            this.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message + " Error in Load of Errored Workflows");
                    }
                }
                else
                {
                    MessageBox.Show("Please select an item to Restart or Cancel the Workflows");
                }
                #endregion To Restart the Workflow
            }
            catch (Exception ex)
            {
            }
            
        }

        /// <summary>
        /// Restart the workflows in error
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                #region To Cancel the Workflow
                string[] checkedItems = GetCheckedItems();

                if (checkedItems != null)
                {
                    try
                    {
                        using (SPSite site = new SPSite(siteName))
                        {
                            SPWeb web = site.OpenWeb();
                            SPList list = web.Lists[listName];
                            SPWorkflowCollection workflowCollection;
                            string result = string.Empty;

                            int count = checkedItems.Length - 1;
                            int n = 0;

                            objWorkflowAssociationCollection = list.WorkflowAssociations;

                            foreach (SPListItem listItem in list.Items)
                            {
                                workflowCollection = listItem.Workflows;

                                for (int x = 0; x < workflowCollection.Count; x++)
                                {
                                    SPWorkflow wf = workflowCollection[x];
                                    if (wf.ParentAssociation.Name == workflowName)
                                    {
                                        Guid wfInstanceID = wf.InstanceId;
                                        var workflowStatusValue = listItem[workflowName];

                                        SPWorkflowAssociation wfAssociation = list.WorkflowAssociations[wf.AssociationId];
                                        string workflowStatusString = System.Enum.GetName(typeof(SPWorkflowStatus), Convert.ToInt32(workflowStatusValue));

                                        if (n <= count)
                                        {
                                            string checkedItemName = checkedItems[n].ToString();

                                            if (listItem.Name == checkedItemName)
                                            {
                                                SPWorkflowManager.CancelWorkflow(wf);
                                                n++;
                                                result += checkedItemName + "\n";
                                            }
                                        }
                                    }
                                }
                            }
                            MessageBox.Show(result + " is/are Cancelled.", "Information");
                            this.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message + " Error in Load of Errored Workflows");
                    }
                }
                else
                {
                    MessageBox.Show("Please select an item to Restart or Cancel the Workflows");
                }
                #endregion To Cancel the Workflow
            }
            catch (Exception ex)
            {
            }
            
        }

        #region Utilities
        private string[] GetCheckedItems()
        {
            #region Check if an Item is Selected
            int checkedCount = checkedListBox1.CheckedItems.Count;
            if (checkedCount > 0)
            {
                string[] checkedItemName = new string[checkedCount];
                for (int i = 0; i < checkedCount; i++)
                {
                    //string checkedItemName = checkedListBox1.CheckedItems[i].ToString();
                    checkedItemName[i] = checkedListBox1.CheckedItems[i].ToString();
                }
                return checkedItemName;
            }
            return null;
            #endregion Check if an Item is Selected
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion Utilities
    }
}
